package java_thinking.unit_21._21_8;

import net.jcip.annotations.ThreadSafe;

import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.Semaphore;

/**
 * @Desc:   8-4 使用 Semaphore 来控制任务的提交速率
 *          1.该方法使用了一个无界队列，因为不能限制队列的大小和任务的到达率，
 *            并设置信号的上界设置为线程池的大小加上可排队的任务的数量，这是因为
 *            信号量需要控制正在执行和等待执行的任务数量；
 * @author: cww
 * @DateTime: 2019/6/17 20:08
 */
@ThreadSafe
public class BoundedExecutor {
    private final Executor exec;
    private final Semaphore semaphore;

    public BoundedExecutor(Executor exec, int bound) {
        this.exec = exec;
        this.semaphore = new Semaphore(bound);
    }
    public void submitTask(final Runnable command) throws InterruptedException {
        semaphore.acquire();
        try {
            exec.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        command.run();
                    } finally {
                        semaphore.release();
                    }
                }
            });
        } catch (RejectedExecutionException e) {
            semaphore.release();
        }
    }
}
